<template>
  <div class="w-full h-full p-2 text-fontPrimary flex flex-col items-center bg-AiChatMain text-white">
    <!-- 头部 -->
    <div class="w-full flex flex-row justify-between items-center">
      <span class="text-xl font-medium">快速聊天</span>
      <CloseOutline class="w-[20px] h-[20px] text-base cursor-pointer" @click="Close" />
    </div>

    <!-- 内容区 -->
    <div class="w-full flex-1 flex flex-col justify-center items-center">
      <!-- 欢迎页 -->
      <div class="w-full text-center" v-if="isWelcome">
        <img alt="logo" class="w-[100px] h-[100px] m-auto" src="@/assets/images/openai.svg" />
        <p class="mt-2">NexaAI</p>
        <p class="text-xs text-fontPlaceholde mt-2">AI 有时也可能出错，请仔细辨别信息</p>
      </div>

      <!-- 消息列表 -->
      <div v-else class="w-full h-[calc(100vh-190px)] overflow-y-scroll scrollbar" ref="messageListRef">
        <div class="w-full rounded-lg p-2" v-for="(item, index) in ai.AiMessageList" :key="index">
          <template v-if="item.type != 2">
            <div class="w-full flex flex-row-reverse items-center gap-2">
              <n-avatar :src="user.avatar" :size="30" />
              <div class="bg-[#414158] p-2 rounded-xl">
                {{ item.content }}
              </div>
            </div>
          </template>
          <template v-else>
            <div class="grid grid-cols-[30px_1fr] items-start gap-2">
              <img alt="logo" class="w-[30px] h-[30px]" src="@/assets/images/openai.svg" />
              <MdPreview :id="id" :modelValue="item.content" theme="dark" class="px-2 pb-2 rounded" />
            </div>
          </template>
        </div>
      </div>
    </div>

    <!-- 输入框 -->
    <div class="w-full bg-AiChatInput m-auto rounded-lg overflow-hidden p-2">
      <textarea
        class="w-full h-[60px] bg-AiChatInput p-2 border-none resize-none focus:outline-none"
        v-model="askValue"
      ></textarea>
      <p class="flex flex-row justify-end items-center px-3 gap-5 cursor-pointer">
        <span class="iconfont icon-fujian" style="font-size: 20px"></span>
        <el-button type="primary" size="small" @click="SendToAi">发送</el-button>
      </p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { nextTick, ref } from "vue";
import { TryAskAi } from "@/api/ai";
import { UseAI } from "@/store/modules/ai";
import { useUser } from "@/store/modules/user";
import { NAvatar } from "naive-ui";
import { CloseOutline } from "@vicons/ionicons5";
import { MdPreview } from "md-editor-v3";
import "md-editor-v3/lib/preview.css";

const user = useUser();
const ai = UseAI();
const id = "preview-only";
const isWelcome = ref(true);
let askValue = ref("");
let controller = ref<AbortController | null>(null);
const messageListRef = ref();

// 关闭窗口
function Close() {
  window.electronApi.controlTabBar({ obj: "quickAsk", type: "close" });
}

// 取消请求
function AbortAiRequest() {
  if (controller.value) {
    controller.value.abort();
    controller.value = null;
  }
}

// 发送消息给Ai
async function SendToAi() {
  const content = askValue.value.trim();
  if (!content) return;
  askValue.value = "";
  isWelcome.value = false;
  AbortAiRequest();
  controller.value = new AbortController();
  ai.AiMessageList.push({ content, type: 1 });
  try {
    await ScrollBottom();
    ai.AiMessageList.push({ content: "", type: 2 });
    const aiMessageIndex = ai.AiMessageList.length - 1;
    const response = await TryAskAi({
      sessionId: user.userInfo?.quickAskId,
      content,
      signal: controller.value.signal,
    });
    const reader = response.body?.getReader();
    if (!reader) {
      console.error("获取消息失败");
      return;
    }
    const decoder = new TextDecoder("utf-8");
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      ai.AiMessageList[aiMessageIndex].content += decoder.decode(value, {
        stream: true,
      });
      await ScrollBottom();
    }
  } catch (error: any) {
    if (error.name !== "AbortError") {
      console.error("Error while sending to AI:", error);
    }
  } finally {
    controller.value = null;
  }
}

// 滚动到底部
async function ScrollBottom(smooth = true) {
  await nextTick();
  if (!messageListRef.value) return;
  const container = messageListRef.value;
  if (container.scrollHeight <= 0) return;
  container.scrollTo({
    top: container.scrollHeight,
    behavior: smooth ? "smooth" : "auto",
  });
  const checkScroll = () => {
    if (container.scrollHeight > container.scrollTop + container.clientHeight) {
      container.scrollTo({
        top: container.scrollHeight,
        behavior: smooth ? "smooth" : "auto",
      });
    }
  };
  const observer = new MutationObserver(checkScroll);
  observer.observe(container, { childList: true, subtree: true });
  setTimeout(() => {
    observer.disconnect();
  }, 1000);
}
</script>

<style lang="scss" scoped></style>
